package com.charlessong.hcnetsdk.demo.alarm;

import com.alibaba.fastjson.JSONArray;
import com.sun.jna.Pointer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.ContextStoppedEvent;
import org.springframework.stereotype.Component;

/**
 * @author charles
 * @Date 2021/11/30
 */
@Slf4j
@Component
public class AlarmListener implements ApplicationListener<ApplicationEvent> {
    @Value("${device.ip}")
    private String deviceIp;

    @Value("${device.port}")
    private String devicePort;

    @Value("${device.username}")
    private String username;

    @Value("${device.password}")
    private String password;


    public static FMSGCallBack_V31 fMSFCallBack_V31;//报警回调函数实现

    public class FMSGCallBack_V31 implements HCNetSDK.FMSGCallBack_V31 {
        //报警信息回调函数
        public boolean invoke(int lCommand, HCNetSDK.NET_DVR_ALARMER pAlarmer, Pointer pAlarmInfo, int dwBufLen, Pointer pUser) {
            log.error("====> 报警函数 invoke");
            AlarmDataHandle(lCommand, pAlarmer, pAlarmInfo, dwBufLen, pUser);
            return true;
        }
    }

    @Override
    public void onApplicationEvent(ApplicationEvent applicationEvent) {
        if (applicationEvent instanceof ContextRefreshedEvent || applicationEvent instanceof ContextStoppedEvent) {
            log.info("====================================");
            try {
                HCNetSDK hCNetSDK = HCNetSDK.INSTANCE;
                int lUserID = -1;
                int lAlarmHandle = -1;

                if (applicationEvent instanceof ContextRefreshedEvent) {
                    lUserID = HCNetSDKUtils.login(deviceIp, Short.valueOf(devicePort), username, password);

                    //设置回调接口
                    if (fMSFCallBack_V31 == null) {
                        fMSFCallBack_V31 = new FMSGCallBack_V31();
                        Pointer pUser = null;
                        if (!hCNetSDK.NET_DVR_SetDVRMessageCallBack_V31(fMSFCallBack_V31, pUser)) {
                            log.error("====>设置回调函数失败!");
                            System.out.println("========setting callback function fail,error:" + hCNetSDK.NET_DVR_GetLastError());
                        }
                    }

                    lAlarmHandle=HCNetSDKUtils.setUpAlarm();

                    JSONArray cards=HCNetSDKUtils.listCards();
                    log.info("========>所有门禁卡信息=========\n{}",cards);
                } else {
                    HCNetSDKUtils.logout();
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        }
    }

    public void AlarmDataHandle(int lCommand, HCNetSDK.NET_DVR_ALARMER pAlarmer, Pointer pAlarmInfo, int dwBufLen, Pointer pUser) {
        log.error("====> lCommand:{}", lCommand);
        log.error("====> pAlarmer{}", pAlarmer);
        log.error("====> pAlarmer Details");
        log.error("====> pAlarmInfo:{}", pAlarmInfo);

        System.out.println("====> lCommand:{}" + lCommand);
        System.out.println("====> pAlarmer{}" + pAlarmer.toString());
        System.out.println("====> pAlarmer Details");
        System.out.println("====> pAlarmInfo:{}" + pAlarmInfo.toString());


        try {
            String sAlarmType = new String();
            sAlarmType = new String("lCommand=0x") + Integer.toHexString(lCommand);
            //lCommand是传的报警类型
            switch (lCommand) {
                case HCNetSDK.COMM_ALARM_ACS:
                    //门禁主机报警信息
                    HCNetSDK.NET_DVR_ACS_ALARM_INFO strACSInfo = new HCNetSDK.NET_DVR_ACS_ALARM_INFO();
                    strACSInfo.write();
                    Pointer pACSInfo = strACSInfo.getPointer();
                    pACSInfo.write(0, pAlarmInfo.getByteArray(0, strACSInfo.size()), 0, strACSInfo.size());
                    strACSInfo.read();

                    sAlarmType = sAlarmType + "：alarm info，username：" + new String(strACSInfo.sNetUser).trim() + "time：" + strACSInfo.struTime.toString() + "，cardno：" + new String(strACSInfo.struAcsEventInfo.byCardNo).trim() + "，卡类型：" +
                            strACSInfo.struAcsEventInfo.byCardType + "，alarm type：" + strACSInfo.dwMajor + "，alarm type2：" + strACSInfo.dwMinor;
                    log.error("====> 门禁主机报警信息:{}", sAlarmType);
                    break;
                default:
                    break;
            }
        } catch (Exception ex) {
            log.error("====> 报警回调数据处理异常", ex);
        }
    }
}
